package cn._2dland.http.method;

import java.io.ByteArrayOutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import cn._2dland.http.method.multiparts.Part;

public class PostMethod extends HttpMethod {
	/** multipart模式下的分隔符 */
	private String boundary = null;

	/** 数据块 */
	private List<Part> parts = null;

	public PostMethod() {
		this(null);
	}
	public PostMethod(String url) {
		super(url);
		boundary = Long.toHexString(System.currentTimeMillis());
		parts = new ArrayList<Part>();
	}

	public String getMethodName() {
		return "POST";
	}

	public String getURL() {
		return this.url;
	}

	public byte[] getData() {
		return parts.isEmpty() ? getURLEncodedData() : getMultipartData();
	}

	/**
	 * 使用URLEncoded编码
	 * @return
	 */
	private byte[] getURLEncodedData() {
		byte[] data = null;

		if(parameters != null) {
			StringBuffer paramBuf = new StringBuffer();
			String sep = "";
			for(String paramName : parameters.keySet()) {
				String paramValue = parameters.get(paramName);
				try {
					paramValue = URLEncoder.encode(paramValue, "utf-8");
				} catch (Exception e) {}

				paramBuf.append(sep).append(paramName).append("=").append(paramValue);
				sep = "&";
			}

			String paramStr = paramBuf.toString();
			try { data = paramStr.getBytes(params.getClientCharset()); }
			catch (Exception e) { data = paramStr.getBytes(); }
		}

		return data;
	}

	/**
	 * 使用multipart编码
	 * @return
	 */
	private byte[] getMultipartData() {
		byte[] result = null;
		try {
			ByteArrayOutputStream ba = new ByteArrayOutputStream();
			String buf = new StringBuffer().append("--").append(boundary).append(Part.CRLF).toString();
			// 循环写入每个part
			for(int i=0; i<parts.size(); i++) {
				// 写入分隔符
				ba.write(buf.getBytes());
				// 写入分段数据
				Part p = parts.get(i);
				p.setCharset(params.getClientCharset());
				ba.write(p.getBytes());
			}
			// 写入结尾信息
			buf = new StringBuffer().append("--").append(boundary).append("--").append(Part.CRLF).toString();
			ba.write(buf.toString().getBytes());
			// 取出字节数组
			ba.flush();
			result = ba.toByteArray();

			// 释放资源
			ba.close();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 添加一个分段
	 * @param part
	 */
	public void addPart(Part part) {
		parts.add(part);
	}

	@Override
	public int execute() {
		String contentType = parts.isEmpty() ? 
				"application/x-www-form-urlencoded" : "multipart/form-data; boundary=" + boundary;
		addRequestHeader("Content-Type", contentType);
		return super.execute();
	}
}
